#ifndef __THREADPOOL_H__
#define __THREADPOOL_H__

// 线程池的设计目标正是通过复用有限数量的线程，来处理潜在的海量任务。
// 这样可以避免频繁创建和销毁线程带来的开销，提高资源利用率。
#include <pthread.h>

struct Task_t
{
    // 回调函数
    // 是一个指向函数的指针，它指向的函数类型的格式是：接受一个 void * 类型的参数，返回一个 void * 类型的值
    // void *：表示该函数的返回类型是 void *，即返回一个指向任意类型的指针
    // (*function)：表示 function 是一个指向函数的指针
    // (void *arg)：表示该函数接受一个 void * 类型的参数
    void *(*function)(void *arg);
    // 回调函数的参数
    void *arg;
};

// 管理者线程
void *managerThreadFunc(void *arg);
// 线程工作函数
void *workerThreadFunc(void *arg);

class ThreadPool
{
public:
    // 友元
    friend void *managerThreadFunc(void *arg);
    friend void *workerThreadFunc(void *arg);

public:
    // 构造函数
    ThreadPool(int minThread, int maxThread, int maxQueueCapacity);
    // 析构函数
    ~ThreadPool();
public:
    // 添加任务
    void addTask(void *(*function)(void *arg), void *arg);
private:
    // 线程退出
    void exitThread(pthread_t tid);
private:
    // 任务队列
    Task_t *m_queue; // 动态数组
    // 队列容量
    int m_queueCapacity;
    // 队列的元素个数
    int m_queueSize;
    // 队头
    int m_queueFront;
    // 队尾
    int m_queueTail;

    // 工作线程
    pthread_t *m_threadId;
    // 管理者线程（用于调度）
    pthread_t m_managerThreadId;
    // 存活的线程数
    int m_aliveThreadNum;
    // 忙碌的线程数
    int m_busyThreadNum;
    // 最小的线程数（下限）
    int m_minThreadNum;
    // 最大的线程数（上限）
    int m_maxThreadNum;

    // 锁
    pthread_mutex_t m_mutex;
    // 忙碌锁
    pthread_mutex_t m_busyMutex;
    // 条件变量：等队列有数据
    pthread_cond_t m_queueNotEmpty;
    // 条件变量：等队列不满
    pthread_cond_t m_queueNotFull;

    // 要减少的线程数
    int exitNum;
};

#endif // __THREADPOOL_H__